﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using log4net;
using System.Reflection;
using System.IO;

namespace SopCastRecorder
{
	public partial class OptionForm : Form
	{
		private static ILog logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

		public OptionForm()
		{
			InitializeComponent();
		}

		private void OptionForm_Load(object sender, EventArgs e)
		{
			try
			{
				this.Init();
			}
			catch (Exception exception1)
			{
				logger.Error(MethodBase.GetCurrentMethod().Name, exception1);
				Form1.SetErrorStatus();
			}
		}

		private void Init()
		{
			this.SetValueToWindow();
		}

		private void SetValueToWindow()
		{
			// 変更前の値と比較するため、編集用のインスタンスを作る
			var channels = new List<Channel>();
			foreach (var channel in OptionFile.Option1.Channels)
			{
				channels.Add(new Channel()
				{
					Name = channel.Name,
					Address = channel.Address
				});
			}
			this.bindingSource1.DataSource = channels;
			this.dataGridView1.DataSource = null;
			this.dataGridView1.DataSource = this.bindingSource1;

			this.txtWait.Text = OptionFile.Option1.Wait.ToString();
			this.txtFileNameFormat.Text = OptionFile.Option1.FileNameFormat;
			this.txtExtention.Text = OptionFile.Option1.Extention;
			this.txtSopCastPath.Text = OptionFile.Option1.SopCastPath;
			this.txtNgCaptionRegex.Text = OptionFile.Option1.NgCaptionRegex;
			this.txtBodyCaptionRegex.Text = OptionFile.Option1.BodyCaptionRegex;
			this.txtDialogCaptionRegex.Text = OptionFile.Option1.DialogCaptionRegex;
			this.txtSopCastBodyAddressTextIndex.Text = OptionFile.Option1.SopCastBodyAddressTextIndex.ToString();
			this.txtSopCastPlayerRecordButtonIndex.Text = OptionFile.Option1.SopCastPlayerRecordButtonIndex.ToString();
			this.txtSopCastSaveDialogInputTextIndex.Text = OptionFile.Option1.SopCastSaveDialogInputTextIndex.ToString();
		}

		private void btnEditFile_Click(object sender, EventArgs e)
		{
			try
			{
				this.EditFile();
			}
			catch (Exception exception1)
			{
				logger.Error(MethodBase.GetCurrentMethod().Name, exception1);
				Form1.SetErrorStatus();
			}
		}

		private void EditFile()
		{
			this.Save();
			var form = new EditorForm();
			form.Path = OptionFile.FileName;
			form.Show();
		}

		private void Save()
		{
		}

		private void btnSopCastPath_Click(object sender, EventArgs e)
		{
			try
			{
				this.SopCastPath(this.txtSopCastPath);
			}
			catch (Exception exception1)
			{
				logger.Error(MethodBase.GetCurrentMethod().Name, exception1);
				Form1.SetErrorStatus();
			}
		}

		private void SopCastPath(TextBox txt)
		{
			var dialog = new OpenFileDialog();
			if (!string.IsNullOrEmpty(txt.Text))
			{
				try
				{
					var f = new FileInfo(txt.Text);
					dialog.InitialDirectory = f.DirectoryName;
					dialog.FileName = f.Name;
				}
				catch
				{
				}
			}
			if (dialog.ShowDialog() == DialogResult.OK)
			{
				txt.Text = dialog.FileName;
			}
		}

		private void btnReload_Click(object sender, EventArgs e)
		{
			try
			{
				this.Reload();
			}
			catch (Exception exception1)
			{
				logger.Error(MethodBase.GetCurrentMethod().Name, exception1);
				Form1.SetErrorStatus();
			}
		}

		private void Reload()
		{
			OptionFile.Read();
			this.SetValueToWindow();
		}

		private void btnOk_Click(object sender, EventArgs e)
		{
			try
			{
				this.Ok();
			}
			catch (Exception exception1)
			{
				logger.Error(MethodBase.GetCurrentMethod().Name, exception1);
				Form1.SetErrorStatus();
			}
		}

		public Action CallbackOk;
		private void Ok()
		{
			this.SetValueToOption();
			OptionFile.Write();
			this.CallbackOk.Invoke();
			this.Close();
		}

		private void SetValueToOption()
		{
			this.ConvertChannelName();
			int iWait;
			if (!int.TryParse(this.txtWait.Text, out iWait))
			{
				iWait = Option.DefaultWait;
			}
			int iSopCastBodyAddressTextIndex;
			if (!int.TryParse(this.txtSopCastBodyAddressTextIndex.Text, out iSopCastBodyAddressTextIndex))
			{
				iSopCastBodyAddressTextIndex = Option.DefaultSopCastBodyAddressTextIndex;
			}
			int iSopCastPlayerRecordButtonIndex;
			if (!int.TryParse(this.txtSopCastPlayerRecordButtonIndex.Text, out iSopCastPlayerRecordButtonIndex))
			{
				iSopCastPlayerRecordButtonIndex = Option.DefaultSopCastPlayerRecordButtonIndex;
			}
			int iSopCastSaveDialogInputTextIndex;
			if (!int.TryParse(this.txtSopCastSaveDialogInputTextIndex.Text, out iSopCastSaveDialogInputTextIndex))
			{
				iSopCastSaveDialogInputTextIndex = Option.DefaultSopCastSaveDialogInputTextIndex;
			}
			OptionFile.Option1.Wait = iWait;
			OptionFile.Option1.FileNameFormat = this.txtFileNameFormat.Text;
			OptionFile.Option1.Extention = this.txtExtention.Text;
			OptionFile.Option1.SopCastPath = this.txtSopCastPath.Text;
			OptionFile.Option1.NgCaptionRegex = this.txtNgCaptionRegex.Text;
			OptionFile.Option1.BodyCaptionRegex = this.txtBodyCaptionRegex.Text;
			OptionFile.Option1.DialogCaptionRegex = this.txtDialogCaptionRegex.Text;
			OptionFile.Option1.SopCastBodyAddressTextIndex = iSopCastBodyAddressTextIndex;
			OptionFile.Option1.SopCastPlayerRecordButtonIndex = iSopCastPlayerRecordButtonIndex;
			OptionFile.Option1.SopCastSaveDialogInputTextIndex = iSopCastSaveDialogInputTextIndex;
		}

		private void ConvertChannelName()
		{
			this.bindingSource1.EndEdit();
			var afterChannels = (List<Channel>)this.bindingSource1.DataSource;
			foreach(var scheduleInfo in OptionFile.Option1.ScheduleInfoes)
			{
				var address = Channel.GetAddress(scheduleInfo.Channel);
				if (address == null)
				{
					scheduleInfo.Channel = null;
					continue;
				}

				var v =
					from p in afterChannels
					where p.Address == address
					select p;
				if (v.Count() == 0)
				{
					scheduleInfo.Channel = null;
					continue;
				}

				scheduleInfo.Channel = v.First().Name;
			}

			OptionFile.Option1.Channels = afterChannels;
		}
	}
}
